/**
 * @file Thread.cc
 * @author zziywang (zziywang@163.com)
 * @brief { life is too short to learn cpp! }
 * @version 1.0
 * @date 2022-05-08
 *
 * @copyright Copyright (c) 2022
 *
 */

#include "Thread.hh"
#include <stdio.h>

namespace snow
{

namespace tls
{
__thread const char *threadName = "AnonymousThread";
} // namespace tls

struct ThreadData {
    ThreadData(const string &name, const ThreadCallBack &cb)
        : name_(name), cb_(std::move(cb)) {}
    void runInThread()
    {
        tls::threadName =
            name_ != string() ? name_.c_str() : "AnonymousThread";
        // 执行前...
        printf("ThreadData::runInThread\n");
        if (cb_) {
            cb_(); // 执行回调函数
        }
        // 执行后...
    }  

    string name_;
    ThreadCallBack cb_;
};

Thread::Thread(const ThreadCallBack &cb, const string &name)
    : pthid_(0), isRunning_(false), cb_(std::move(cb)), name_(name) {}

Thread::~Thread()
{
    if (isRunning_) {
        int ret = pthread_detach(pthid_);
        if (-1 == ret) {
            perror("pthread_detach");
        }
    }
}

// 创建线程
void Thread::start()
{
    // int ret = pthread_create(&pthid_, nullptr, threadFunc, this);
    ThreadData *ptd = new ThreadData(name_, std::move(cb_));
    int ret = pthread_create(&pthid_, nullptr, threadFunc, ptd);
    if (-1 == ret) {
        perror("pthread_create");
        return;
    }
    isRunning_ = true;
}
// 等待回收
void Thread::join()
{
    if (isRunning_) {
        isRunning_ = false;
        int ret = pthread_join(pthid_, nullptr);
        if (-1 == ret) {
            perror("pthread_join");
            return;
        }
    }
}

// 线程入口函数
void *Thread::threadFunc(void *arg)
{
    // Thread *pthread = static_cast<Thread *>(arg);
    // pthread->cb_(); // 执行回调函数
    // return nullptr;

    ThreadData *ptd = static_cast<ThreadData *>(arg);
    ptd->runInThread();
    return nullptr;
}

} // namespace snow